﻿#define _CRT_SECURE_NO_WARNINGS


//字符与字符串函数定义可以参考下面的网站

//https://zh.cppreference.com/w/c/string/byte

//#define NDEBUG
//#include <assert.h>


/*
* 字符分类/转换函数//需要包含ctype.h
*/
//写⼀个代码，将字符串中的⼩写字⺟转⼤写，其他字符不变。
//islower 是能够判断参数部分的 c 是否是⼩写字⺟的。
//通过返回值来说明是否是⼩写字⺟，如果是⼩写字⺟就返回非0的整数，如果不是⼩写字⺟，则返回0

//int tolower(int c); //将参数传进去的⼤写字⺟转⼩写
//int toupper(int c); //将参数传进去的⼩写字⺟转⼤写
//#include <stdio.h>
//#include <ctype.h>
//int main()
//{
//	int i = 0;
//	char str[] ="https://gitee.com\n";
//	printf("%s", str);
//	while (str[i])
//	{
//		if (islower(str[i]))
//		{
//			//str[i] -= 32;
//			str[i] = toupper(str[i]);
//		}
//		putchar(str[i]);
//		i++;
//	}
//	return 0;
//
//}





/*
* 
字符串以 '\0' 作为结束标志，strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数（不包
含 '\0' )。
• 参数指向的字符串必须要以 '\0' 结束。
• 注意函数的返回值为size_t，是⽆符号的（ 易错 ）
• strlen的使⽤需要包含头⽂件
• 学会strlen函数的模拟实现
*/
//const如果放在*的左边，修饰的是指针指向的内容，保证指针指向的内容不能通过指针来改变。但是指针变量本⾝的内容可变。
//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
//size_t my_strlen_1(const char* my_str)
//{//计数器
//	assert(my_str !=NULL);
//	size_t count = 0;
//	while (*my_str)
//	{
//		count++;
//		my_str++;
//	}
//	return count;
//}
//
//size_t my_strlen_2(const char* my_str)
//{
//	//不创建临时变量
//	assert(my_str != NULL);
//	if (*my_str =='\0')
//	{
//		return 0;
//	}
//	return 1+ my_strlen_2(my_str +1);
//}
//
//size_t my_strlen_3(const char* my_str)
//{
//	//指针-指针
//	assert(my_str != NULL);
//	char* p = my_str;
//	while (*p != '\0')
//	{
//		p++;
//	}
//	return p- my_str;
//}
//int main()
//{
//	
//	char str[] = "https://gitee.com\n";
//	printf("%s", str);
//	printf("strlen\t\t=%zd\n", strlen(str));
//	printf("my_strlen_1\t=%zd\n", my_strlen_1(str));
//	printf("my_strlen_2\t=%zd\n", my_strlen_2(str));
//	printf("my_strlen_3\t=%zd\n", my_strlen_3(str));
//	return 0;
//
//}


/*
* strcpy的使用和模拟实现
* 
* 源字符串必须以 '\0' 结束。
• 会将源字符串中的 '\0' 拷⻉到⽬标空间。
• ⽬标空间必须⾜够⼤，以确保能存放源字符串。
• ⽬标空间必须可修改。
//即不能传入类似于 char* p="hello";这种指针
因为这种指针存储在常量区是不可以更改的

• 学会模拟实现
*/

//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
//
//
//void my_strcpy(char* destination, const char* source)
//{
//
//	assert(destination != NULL);
//	assert(source != NULL);
//	int str_length = 0;
//	str_length=strlen(source);//计算长度
//	//复制
//	for (int i = 0; i < str_length+1; i++)
//	{
//		*(destination + i) =*(source + i);
//	}
//
//	return destination;
//}
///*参考答案*/
////char* my_strcpy(char* dest, const char* src)
////{
////	char* ret = dest;
////	assert(dest != NULL);
////	assert(src != NULL);
//// (*dest= *src)的结果等于*src，若*src为'\0'则为int 0，为假可以退出循环
////	while ((*dest++ = *src++))
////	{
////		;
////	}
////	return ret;
////}
//
//
//int main()
//{
//	
//	char str[] = "https://gitee.com        \n";
//	char str_2[] = "https://lck.com        \n";
//	char str_text[50] ="hell0world\n";
//	printf("str=\n%s", str);
//	printf("str_2=\n%s", str_2);
//	printf("str_text=\n%s\n", str_text);
//
//	printf("strcpy(str_text, str)\n");
//	strcpy(str_text, str);
//	printf("str=\n%s", str);
//	printf("str_text=\n%s\n", str_text);
//
//	printf("my_strcpy(str_text, str_2)\n");
//	my_strcpy(str_text, str_2);
//	printf("str_2=\n%s", str_2);
//	printf("str_text=\n%s", str_text);
//
//
//	int a = 0;
//	int b = 30;
//	printf("\n\na=%d\n", a);
//	printf("b=%d\n", b);
//	printf("%d\n", (a=b));
//	printf("a=%d\n", a);
//	printf("b=%d\n", b);
//	return 0;
//
//}



/*
* strcat的使用和模拟实现
*
源字符串必须以 '\0' 结束。
• ⽬标字符串中也得有 \0 ，否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够的⼤，能容纳下源字符串的内容。
• ⽬标空间必须可修改。
• 字符串⾃⼰给⾃⼰追加，如何？
*/
//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
//
//
//void my_strcat(char* destination, const char* source)
//{
//
//	assert(destination != NULL);
//	assert(source != NULL);
//	int str_source_length = 0, str_destination_length = 0;
//	str_source_length = strlen(source);//计算长度
//	str_destination_length = strlen(destination);//计算长度
//	//复制
//	for (int i = str_destination_length; i < str_destination_length+ str_source_length + 1; i++)
//	{
//		*(destination + i) = *(source + i- str_destination_length);
//	}
//
//	return destination;
//}
///*参考答案*/
////char* my_strcat(char* dest, const char* src)
////{
////	char* ret = dest;
////	assert(dest != NULL);
////	assert(src != NULL);
////	//(*dest= *src)的结果等于*src，若*src为'\0'则为int 0，为假可以退出循环
////	while (*dest)
////	{
////		dest++;//移动指针到dest的'\0'字符处
////	}
////	while ((*dest++ = *src++))
////	{
////		;
////	}
////	return ret;
////}
//
//
//int main()
//{
//
//	char str[] = "+https://gitee.com        \n";
//	char str_2[] = "+https://lck.com        \n";
//	char str_text[100] = "+hell0world\n";
//	printf("str=\n%s", str);
//	printf("str_2=\n%s", str_2);
//	printf("str_text=\n%s\n", str_text);
//
//	printf("strcat(str_text, str)\n");
//	strcat(str_text, str);
//	printf("str=\n%s", str);
//	printf("str_text=\n%s\n", str_text);
//
//	printf("my_strcat(str_text, str_2)\n");
//	my_strcat(str_text, str_2);
//	printf("str_2=\n%s", str_2);
//	printf("str_text=\n%s", str_text);
//
//
//
//	return 0;
//
//}


/*
* strcmp的使⽤和模拟实现
*
标准规定：
◦ 第⼀个字符串⼤于第⼆个字符串，则返回⼤于0的数字
◦ 第⼀个字符串等于第⼆个字符串，则返回0
◦ 第⼀个字符串⼩于第⼆个字符串，则返回⼩于0的数字
◦ 那么如何判断两个字符串？ ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。
*/
//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
//
///*参考答案*/
//int my_strcmp(const char* destination, const char* source)
//{
//
//	assert(destination != NULL);
//	assert(source != NULL);
//
//	while (*destination==*source)
//	{
//		if (*destination == '\0')
//		{
//			return 0;
//		}
//		destination++;
//		source++;
//	}
//	return *destination - *source;
//}
//
//
//
//int main()
//{
//
//	char str[] =   "+https://gitee.com\n";
//	char str_2[] = "+https://gitee.con\n";
//	printf("str=\n%s\n", str);
//	printf("str_2=\n%s\n", str_2);
//	printf("strcmp(str, str_2)=\n%d\n", strcmp(str, str_2));
//
//	printf("my_strcmp(str, str_2)=\n%d\n", my_strcmp(str, str_2));
//
//	return 0;
//
//}


//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
//int main()
//{
//	char str[50] = "-hello,world";
//	char str_2[50] = "+https://gitee.con";
//	printf("str=\n%s\n", str);
//	printf("str_2=\n%s\n", str_2);
//	strncpy(str_2, str, strlen(str));
//	printf("strncpy(str_2, str, strlen(str));\n");
//	printf("str=%s\n", str);
//	printf("str_2=%s\n\n", str_2);
//
//	strncat(str_2, str, strlen(str)-3);
//	printf("strncat(str_2, str, strlen(str)-3);\n");
//	printf("str=%s\n", str);
//	printf("str_2=%s\n\n", str_2);
//
//	
//	printf("strncmp(str, str_2, 5);\n");
//	printf("%d\n", strncmp(str, str_2, 5));
//	printf("strncmp(str, str_2, 20);\n");
//	printf("%d\n", strncmp(str, str_2, 20));
//
//
//	return 0;
//
//}

//strstr//查找子串字符的首次出现
//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
//char* my_strstr(const char* str, const char* substr)
//{
//		char* buffer = NULL;
//		const char* substr_buffer = substr;
//		const char* str_buffer = str;
//		assert(str != NULL);
//		assert(substr != NULL);
//next:
//		str = str_buffer;//确认查到哪里了
//		while (*str !=*substr)//查找str里面substr的第一个字符
//		{
//			if (*str == '\0')
//			{
//				return NULL;
//			}
//			str++;
//		}
//		substr_buffer = substr;//使用缓冲指针检查字符串，避免忘记需要查找的字符串
//		str_buffer = str;//记录查到哪里了
//		while (*str == *substr_buffer)//检查整个字符串是否匹配
//		{
//			substr_buffer++;
//			str++;//不检查'\0'所以必须要在检查到'\0'之前停下
//			if (*substr_buffer == '\0')
//			{
//				return str_buffer;
//			}
//
//		}
//		str_buffer++;//没有找到则跳过当前字符
//goto next;//若没有找到则继续寻找
//}
////参考答案
//
////char* strstr(const char* str1, const char* str2)
////{
////	char* cp = (char*)str1;
////	char* s1, * s2;
////	if (!*str2)
////		return((char*)str1);
////	while (*cp)
////	{
////		s1 = cp;
////		s2 = (char*)str2;
////		while (*s1 && *s2 && !(*s1 - *s2))
////			s1++, s2++;
////		if (!*s2)
////			return(cp);
////		cp++;
////	}
////	return(NULL);
////}
//
//
//int main()
//{
//	char str[] = "This is a simple string";
//	char* pch;
//	//pch = strstr(str, "simple");
//	pch = my_strstr(str, "simple");
//	if (pch==NULL)
//	{
//		printf("pch==NULL\n");
//		return 0;
//	}
//	strncpy(pch, "sample", 6);
//	printf("%s\n", str);
//	return 0;
//}


//strtok函数的使⽤


//#include <stdio.h>
//#include <string.h>
//int main()
//{
//	char arr[] = "192.168.6.111";
//	char* sep = ".";
//	char* str = NULL;
//	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
//	{
//		printf("%s\n", str);
//	}
//	return 0;
//}

//strerror函数的使⽤
/*
* strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。
在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码，⼀般是放在 errno.h 这个头⽂件中说明
的，C语⾔程序启动的时候就会使⽤⼀个全局的变量errno来记录程序的当前错误码，只不过程序启动
的时候errno是0，表⽰没有错误，当我们在使⽤标准库中的函数的时候发⽣了某种错误，就会将对应
的错误码，存放在errno中，⽽⼀个错误码的数字是整数很难理解是什么意思，所以每⼀个错误码都是
有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
*/

#include <errno.h>
#include <string.h>
#include <stdio.h>

int main()
{
	int i = 0;
	for (i = 0; i <= 10; i++) {
		printf("%s\n", strerror(i));
	}
	return 0;
}